feat: support Individual API Keys (issuer-less JWT)#4
feat: support Individual API Keys (issuer-less JWT)#4conversun wants to merge 10 commits intozelentsov-dev:developfrom
Conversation
… Keys Company now distinguishes Team and Individual API keys via an optional issuerID and a computed isIndividualKey flag, while encoding omits issuer_id when absent. Added a dedicated individual-key fixture plus tests covering decode, encode, roundtrip, and mixed config decoding; temporary caller fallbacks keep the tree building until later JWT/config waves. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Apple requires Team Key JWTs to use iss and Individual Key JWTs to omit iss entirely and send sub="user". Team key behavior remains unchanged, and the new tests verify both payload shapes plus header and expiration parity. Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…Keys Support loading both single-company and multi-company App Store Connect config from environment variables without requiring issuer IDs, while preserving Team key behavior. Also make environment loading testable via dependency injection and add coverage for Team and Individual key env combinations.
Show Individual Key vs Team Key consistently in company list, switch/current handlers, startup reinitialization logs, and the integration test helper. Also guard test mode against missing configuration so the smoke path exits cleanly without crashing.
- README.md: add Individual API Keys subsection with env var and JSON config examples, plus limitations warning - CLAUDE.md: note that issuerID is optional for Individual Keys; add Individual API Keys note in Environment Configuration - companies.example.json: add third company example without issuer_id for Individual Key configuration
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f23e04bf6d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } catch { | ||
| print("\n⚠️ Test mode exited early: \(error.localizedDescription)", to: &standardError) | ||
| } |
There was a problem hiding this comment.
Re-throw failures in debug test mode
Catching all errors here and then returning makes asc-mcp --test exit successfully even when testAppMetadata() or testCompanySwitching() fails. That regresses test-mode behavior from fail-fast to silent success, which can mask real breakages in local/CI smoke checks that rely on process exit status. Log the error if needed, but propagate it (or call exit(1)) so failed test runs are observable.
Useful? React with 👍 / 👎.
Summary
Adds support for App Store Connect Individual API Keys, which use a different JWT shape than Team Keys (no issuer ID,
sub: "user"instead ofiss). Team Key behavior is fully preserved — this is purely additive.Per Apple's spec:
issclaimissand usessub: \"user\"Changes
Model (
Company)issuerIDis nowString?with a computedisIndividualKeyflagencode(to:)omitsissuer_idfrom JSON when absent → backward compatible with existing Team Key configsJWT (
JWTService)JWTPayloadcustom encoder skips nil claims so the wire format matches Apple's spec exactlyConfig loading
ASC_ISSUER_IDis now optionalASC_COMPANY_N_ISSUER_IDis now optionalUX
--testmode guards against missing config (no crash on smoke path)Docs
README.md— Individual API Keys subsection with env + JSON examples and access limitationsCLAUDE.md— note thatissuerIDis optional for Individual Keyscompanies.example.json— third example withoutissuer_idLimitations (documented)
Individual API Keys cannot access:
Calls to those will fail with 403 at the Apple API level — no client-side pre-validation.
Test Plan
Backward Compatibility